home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / ncsat.cpt / Telnet2.5 final / tcpip / protinit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-17  |  9.4 KB  |  349 lines

  1. /*
  2. *  Protinit.c
  3. *  initialize the template packets
  4. ****************************************************************************
  5. *                                                                          *
  6. *      part of:                                                            *
  7. *      TCP/UDP/ICMP/IP Network kernel for NCSA Telnet                      *
  8. *      by Tim Krauskopf                                                    *
  9. *                                                                          *
  10. *      National Center for Supercomputing Applications                     *
  11. *      152 Computing Applications Building                                 *
  12. *      605 E. Springfield Ave.                                             *
  13. *      Champaign, IL  61820                                                *
  14. *                                                                          *
  15. *    Copyright (c) 1987, Board of Trustees of the University of Illinois   *
  16. *                                                                          *
  17. ****************************************************************************
  18. *   'protinit' initializes packets to make them ready for transmission.
  19. *   For many purposes, pre-initialized packets are created for use by the
  20. *   protocol routines, especially to save time creating packets for
  21. *   transmit.
  22. *
  23. *   Assumes that 'myaddr' is already set to my Ethernet hardware address
  24. *   and any other similar protocol addresses are already initialized 
  25. *   (known) for the local station.
  26. *
  27. *   As this is a convenient place for it, this file contains many of the
  28. *   data declarations for packets which are mostly static (pre-allocated).
  29. */
  30. #include <stdio.h>
  31. #include <string.h>
  32.  
  33. #include <Events.h>
  34. #include <Memory.h>
  35.  
  36. #include "protocol.h"
  37. #include "data.h"
  38. #include "tools.h"
  39. #include "user.h"
  40.  
  41. #define UNKNOWN_PORT_TYPE    0        /* BYU 2.4.16 */
  42. #define MACTCP_PORT_TYPE    1        /* BYU 2.4.16 */
  43. #define NCSA_PORT_TYPE        2        /* BYU 2.4.16 */
  44.  
  45. extern unsigned char SLIP_ip_number[];        /* BYU 2.4.15 */
  46.  
  47. extern short porttype[];                    /* BYU 2.4.16 */
  48.  
  49. /*************************************************************************/
  50. /*  Ethernet headers, initialize a default header to be used in 
  51. *   subsequent pre-initialized headers.  This does something similar for
  52. *   AppleTalk.
  53. */
  54.  
  55. void etherinit
  56.   (
  57.     void
  58.   )
  59.     {
  60.     movebytes(broadaddr,bseed,DADDLEN);
  61.     movebytes(blankd.dest,broadaddr,DADDLEN);    /* some are broadcast */
  62.     movebytes(blankd.me,nnmyaddr,DADDLEN);        /* always from me */
  63.  
  64.     blankd.type = EIP;                /* mostly IP packets */
  65.  
  66. }
  67.  
  68. /*************************************************************************/
  69. /*  ARP packets
  70. *
  71. *   a very limited type of packet goes out.  We currently only talk IP, so
  72. *   initialize as many fields as possible, most fields are already known.
  73. *
  74. *   Also initialize a reverse-arp packet to be sent out on request. (later)
  75. */
  76.  
  77. void arpinit
  78.   (
  79.     void
  80.   )
  81.     {
  82.     int i;
  83.  
  84.     movebytes(&arp.d,&blankd,sizeof(DLAYER));
  85.  
  86.     arp.d.type = EARP;                /* 0x0806 is ARP type */
  87.  
  88.     arp.hrd = intswap(HTYPE);            /*  Ether = 1 */
  89.     arp.pro = intswap(ARPPRO);            /* IP protocol = 0x0800 */
  90.     arp.hln = DADDLEN;                    /* Ethernet hardware length */
  91.     arp.pln = 4;                        /* IP length = 4 */
  92.     
  93.     movebytes(arp.sha,nnmyaddr,DADDLEN);    /* sender's hardware addr */
  94.     movebytes(arp.tha,broadaddr,DADDLEN);    /* target hardware addr */
  95.  
  96.     movebytes(arp.spa,nnipnum,4);        /* sender's IP addr */
  97.  
  98. /*
  99. *  initialize the ARP cache to 0 time, none are gateways to start
  100. */
  101.     for (i=0; i<CACHELEN; i++) {
  102.         arpc[i].tm = 0L;
  103.         arpc[i].gate = 0;
  104.     }
  105.  
  106. }
  107.  
  108. /*************************************************************************/
  109. /*  Internet protocol
  110. *   initialize one packet to use for arbitrary internet transmission.
  111. *   Hopefully, most outgoing IP packets will be pre-initialized by TCP or
  112. *   UDP, but some operations may require a generic IP packet.
  113. */
  114.  
  115. void ipinit
  116.   (
  117.     void
  118.   )
  119.     {
  120.     movebytes(&blankip.d,&blankd,sizeof(DLAYER));
  121.  
  122.     blankip.i.versionandhdrlen = 0x45;        /* smallest header, version 4 */
  123.     blankip.i.service = 0;                    /* normal service */
  124.  
  125.     blankip.i.tlen = 576;                        /* no data yet, maximum size */
  126.     blankip.i.ident = 0;
  127.     blankip.i.frags = 0;                        /* not a fragment of a packet */
  128.  
  129.     blankip.i.ttl = 100;                        /* 100 seconds should be enough */
  130.     blankip.i.protocol = PROTUDP;                /* default to UDP */
  131.  
  132.     blankip.i.check = 0;                        /* disable checksums for now */
  133.  
  134.     movebytes(blankip.i.ipsource,nnipnum,4);    /* my return address */
  135.     movebytes(blankip.i.ipdest,broadip,4);        /* to ? */
  136.  
  137. #ifdef notneedednow
  138. /*
  139. *  Make a blank ICMP packet for sending ICMP requests or responses
  140. */
  141.     movebytes(&blankicmp,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  142.     blankicmp.i.protocol = PROTICMP;        
  143. #endif
  144.  
  145. /*
  146. *  create a mask which can determine whether a machine is on the same wire
  147. *  or not.  RFC950
  148. *  Only set the mask if not previously set.
  149. *  This mask may be replaced by a higher level request to set the subnet mask.
  150. */
  151.  
  152.     if (comparen(nnmask,"\0\0\0\0",4)) {            /* now blank */
  153.  
  154.         if (!(nnipnum[0] & 0x80))                    /* class A */
  155.             netsetmask(nnamask);
  156.         else if ((nnipnum[0] & 0xC0) == 0x80)        /* class B */
  157.             netsetmask(nnbmask);
  158.         else if ((nnipnum[0] & 0xC0) == 0xC0)        /* class C */
  159.             netsetmask(nncmask);
  160.     }
  161.  
  162. }
  163.  
  164. /**************************************************************************/
  165. /*  TCP stuff
  166. *     get ready for makeport()
  167. *   makeport() actually does the initialization when you open a port
  168. */
  169.  
  170. void tcpinit
  171.   (
  172.     void
  173.   )
  174.     {
  175.     int i;
  176.  
  177.     for (i=0; i < NPORTS; i++) {    /* BYU 2.4.16 */
  178.         portlist[i] = NULL;            /* no ports open yet */
  179.         porttype[i] = UNKNOWN_PORT_TYPE;    /* BYU 2.4.16 */
  180.     }                                        /* BYU 2.4.16 */
  181. }
  182.  
  183. /**************************************************************************/
  184. /*  UDP initialization
  185. *   set up ulist for receive of UDP packets
  186. */
  187.  
  188. void udpinit
  189.   (
  190.     void
  191.   )
  192.     {
  193.     ulist.stale = 1;
  194.     ulist.length = 0;
  195.  
  196.     movebytes(&ulist.udpout,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  197.     ulist.udpout.i.protocol = PROTUDP;                /* UDP type */
  198.     ulist.tcps.z = 0;
  199.     ulist.tcps.proto = PROTUDP;
  200.     movebytes(ulist.tcps.source,nnipnum,4);
  201.     
  202. }
  203.  
  204. /************************************************************************/
  205. /*  main code for protinit()
  206. *   for each new type of protocol, put an initialization call here.
  207. *   There may be some requirement of order of initialization.
  208. */
  209. int protinit
  210.   (
  211.     void
  212.   )
  213.     {
  214.  
  215.     etherinit();
  216.     arpinit();  
  217.     ipinit();
  218.     tcpinit();
  219.     udpinit();
  220.  
  221.     return(0);
  222. }
  223.  
  224. void setupwindow
  225.   (
  226.     struct window *w,
  227.     unsigned int wsize
  228.   )
  229.     {
  230.     w->endbuf = w->where + wsize;
  231.     w->base = w->endlim = w->where;
  232.     w->contain = 0;                        /* nothing here yet */
  233.     w->lasttime = time(NULL);
  234.     w->size = wsize;
  235.     w->push = 0;
  236.  
  237. /*
  238. *  base this on time of day clock, for uniqueness
  239. */
  240.     w->ack = w->nxt = ((w->lasttime << 12) & 0x0fffffff);
  241.  
  242. }
  243.  
  244. /**************************************************************************/
  245. /*  makeport
  246. *
  247. *   This is the intialization for TCP based communication.  When a port
  248. *   needs to be created, this routine is called to do as much pre-initialization
  249. *   as possible to save overhead during operation.
  250. *
  251. *   This structure is created upon open of a port, either listening or 
  252. *   wanting to send.
  253. *
  254. *   A TCP port, in this implementation, includes all of the state data for the
  255. *   port connection, a complete packet for the TCP transmission, and two
  256. *   queues, one each for sending and receiving.  The data associated with
  257. *   the queues is in struct window.
  258. */
  259. int makeport
  260.   (
  261.     short connectionType        /* BYU 2.4.15 - was "void" */
  262.   )
  263.     {
  264.     int i,j,retval;
  265.  
  266.     struct port *p,*q;
  267.  
  268. /*
  269. *  Check to see if any other connection is done with its port buffer space.
  270. *  Indicated by the connection state of SCLOSED
  271. */
  272.     p = NULL;
  273.     i = 0;
  274.     do {
  275.         q = portlist[i];
  276.         if (q != NULL && porttype[i] == NCSA_PORT_TYPE && (q->state == SCLOSED ||    /* BYU 2.4.16 */
  277.         (q->state == STWAIT && q->out.lasttime + WAITTIME < time(NULL)))) 
  278.             p = q;
  279.         retval = i++;                    /* port # to return */
  280.     } while (p == NULL && i < NPORTS);
  281.  
  282. /*  
  283. * None available pre-allocated, get a new one, about 8.5 K with a 4K windowsize
  284. */
  285.     if (p == NULL) {
  286.         p = (struct port *)NewPtr(sizeof(struct port));
  287.  
  288.               for (i=0; portlist[i] != NULL ||                /* BYU 2.4.16 */
  289.                     porttype[i] != UNKNOWN_PORT_TYPE; i++)  /* BYU 2.4.16 */
  290.             if (i >= NPORTS) {
  291.                 nnerror(500);
  292.                 return(-1);                /* out of room for ports */
  293.             }
  294.         portlist[i] = p;
  295.         retval = i;
  296.     }
  297.  
  298.     if (p == NULL) {
  299.         nnerror(505);
  300.         return(-1);
  301.     }
  302.  
  303.     movebytes(&p->tcpout,&blankip,sizeof(DLAYER)+sizeof(IPLAYER));
  304.                                             /* static initialization */
  305.  
  306.     p->tcpout.i.tlen = 0;
  307.     p->tcpout.t.urgent = 0;                    /* no urgent data */
  308.     p->tcpout.t.hlen = 20 << 2;                /* header length << 2 */
  309.     p->tcps.z = 0;
  310.     p->tcps.proto = PROTTCP;
  311.  
  312.     if (connectionType) {                                    /* BYU 2.4.15 */
  313.         movebytes(p->tcpout.i.ipsource,SLIP_ip_number,4);    /* BYU 2.4.15 */
  314.         movebytes(p->tcps.source,SLIP_ip_number,4);            /* BYU 2.4.15 */
  315.     } else                                                    /* BYU 2.4.15 */
  316.         movebytes(p->tcps.source,nnipnum,4);                /* BYU 2.4.15 */
  317.  
  318.     setupwindow(&p->in,WINDOWSIZE);        /* queuing parameters */
  319.     setupwindow(&p->out,WINDOWSIZE);
  320.  
  321.     do {
  322.  
  323.         i = time(NULL);
  324.         i |= 2048;              /* make sure it is at least this large */
  325.         i &= 0x3fff;            /* at least this small */
  326.  
  327.         for (j=0; j<NPORTS && i != portlist[j]->in.port ; j++)
  328.             ;
  329.  
  330.     } while (j < NPORTS);
  331.  
  332.     if ( nnfromport ) {            /* allow the from port to be forced */
  333.         i = nnfromport;
  334.         nnfromport = 0;
  335.     }
  336.  
  337.     p->in.port = i;
  338.  
  339.     p->tcpout.t.source = intswap(i);
  340.     p->tcpout.t.seq = longswap(p->out.nxt);
  341.     
  342.     p->state = SCLOSED;
  343.     p->credit = nncredit;
  344.     p->sendsize = TSENDSIZE;
  345.     p->rto = MINRTO;
  346.  
  347.     return(retval);
  348. }
  349.